#include "proxyclient_service.h"
#include "retcodes.h"
#include "message_factory.h"
#include "GameHostManager.h"
#include "MessageDef.h"
#include "log.h"

CProxyClientService::CProxyClientService()
{
	send_service_msg_session_id_ = 0;
	back_service_msg_session_id_ = 0;

	service_id_ = 0;
	service_type_ = 0;
	//client_net_ = NULL;
	map_area_ = 0;
}

CProxyClientService::~CProxyClientService()
{
	//if (client_net_ != NULL)
	//{
	//	delete client_net_;
	//	client_net_ = NULL;
	//}
}


int32_t CProxyClientService::InitializeServer(int service_type, int service_id, IService* server)
{
	service_type_ = service_type;
	service_id_ = service_id;
	service_ = server;

	

	if (service_type == PLATFORM_SERVICE)
	{
		std::string ip_address = GameHostManager::GetInstance().GetPlatformProxyHostIp();
		int16_t ip_port = GameHostManager::GetInstance().GetPlatformProxyHostListenPort();

		set_ip(ip_address);
		set_port(ip_port);
	}
	else
	{
		std::string ip_address = GameHostManager::GetInstance().GetProxyHostIp();
		int16_t ip_port = GameHostManager::GetInstance().GetProxyHostListenPort();
		set_ip(ip_address);
		set_port(ip_port);
	}


	return ::common::SUCCEED;
}

int32_t CProxyClientService::Finalize()
{
	LOG_INFO("default", "ProxyClientService finalize begin");
	return ::common::SUCCEED;
}

OBJ_ID_TYPE CProxyClientService::AddSendSessionID(OBJ_ID_TYPE session_id)
{
	send_service_msg_session_id_ = session_id;
	return send_service_msg_session_id_;
}

OBJ_ID_TYPE CProxyClientService::GetSendSessionID()
{
	return send_service_msg_session_id_;
}

int CProxyClientService::ClearSendSessionID()
{
	send_service_msg_session_id_ = 0ll;
	return ::common::SUCCEED;
}

OBJ_ID_TYPE CProxyClientService::AddBackSessionID(OBJ_ID_TYPE session_id)
{
	back_service_msg_session_id_ = session_id;
	return back_service_msg_session_id_;
}

OBJ_ID_TYPE CProxyClientService::GetBackSessionID()
{
	return back_service_msg_session_id_;
}

int CProxyClientService::ClearBackSessionID()
{
	back_service_msg_session_id_ = 0ll;
	return ::common::SUCCEED;
}


int CProxyClientService::SendServiceMsg(uint32_t msg_id, const std::string& msg, uint32_t dst_area_id, uint32_t dst_service_type, uint32_t dst_service_id, OBJ_ID_TYPE session_id, int32_t head_extend, int32_t send_platform)
{
	common::CProxyHead head;
	head.src_server_type = service_type_;
	head.src_server_id = service_id_;
	head.src_area_id = GameHostManager::GetInstance().GetServerAreaId();
	head.dst_server_type = dst_service_type;
	head.dst_server_id = dst_service_id;
	// 为了方便，暂时将0作为本服，如果以后要有广播功能，再考虑
	if (dst_area_id == 0)
	{
		dst_area_id = head.src_area_id;
	}
	head.dst_area_id = dst_area_id;
	head.msg_id = msg_id;
	head.extend = head_extend;
	head.send_platform = send_platform;

	ClearSendSessionID();
	ClearBackSessionID();

	return SendMsg(head, msg);
}

int CProxyClientService::SendMsg2Game(uint32_t msg_id, const std::string& msg, int32_t area_id, int server_id)
{
	return SendServiceMsg(msg_id, msg, area_id, GAME_SERVICE, server_id, 0, 0);
}

int CProxyClientService::SendMsg2Map(uint32_t msg_id, const std::string& msg, int32_t area_id /*= 0*/)
{
	if (!area_id) {
		area_id = map_area_;
	}
	return SendServiceMsg(msg_id, msg, area_id, MAP_SERVICE, 0, 0, 0);
}

int CProxyClientService::SendMsg2Chat(uint32_t msg_id, const std::string& msg, int32_t area_id /*= 0*/)
{
	return SendServiceMsg(msg_id, msg, area_id, CHAT_SERVICE, 0, 0, 0);
}

int CProxyClientService::SendMsg2Gate(uint32_t msg_id, const std::string& msg, int area_id)
{
	return SendServiceMsg(msg_id, msg, area_id, GATE_SERVICE, 0, 0, 0);
}

int CProxyClientService::SendMsg2Login(uint32_t msg_id, const std::string& msg, int32_t area_id)
{
	return SendServiceMsg(msg_id, msg, area_id, LOGIN_SERVICE, 0, 0, 0);
}

int CProxyClientService::SendMsg2DB(uint32_t msg_id, const std::string& msg, int msg_split, int32_t dst_area_id)
{
	return SendServiceMsg(msg_id, msg, dst_area_id, DB_SERVICE, 0, 0, msg_split);
}

int CProxyClientService::SendMsg2Log(uint32_t msg_id, const std::string& msg, int msg_split, int32_t area_id)
{
	return SendServiceMsg(msg_id, msg, area_id, LOG_SERVICE, 0, 0, msg_split);
}

int CProxyClientService::SendMsg2Match(uint32_t msg_id, const std::string& msg)
{
	return SendServiceMsg(msg_id, msg, 0, MATCH_SERVICE, 0, 0, 0);
}

int CProxyClientService::SendMsg2Proxy(uint32_t msg_id, const std::string& msg)
{
	return 0;//SendServiceMsg( msg_id, msg, server_gateway_id.value( ), PROXY_SERVICE, 1, 0,  0 );
}

int CProxyClientService::SendResponseMsg(const common::CProxyHead& src_head, uint32_t msg_id, const std::string& msg)
{
	common::CProxyHead head;
	head.src_server_type = service_type_;
	head.src_server_id = service_id_;
	head.src_area_id = GameHostManager::GetInstance().GetServerAreaId();
	head.dst_server_type = src_head.src_server_type;
	head.dst_server_id = src_head.src_server_id;
	head.dst_area_id = src_head.src_area_id;
	head.msg_id = msg_id;

	ClearSendSessionID();
	ClearBackSessionID();

	return SendMsg(head, msg);
}

// client 向proxy 发送信息
int32_t CProxyClientService::SendMsg(::common::CProxyHead& proxy_head, const std::string& msg)
{


	//std::string sendString;
	//uint32_t msg_id = boost::asio::detail::socket_ops::host_to_network_long(proxy_head.msg_id);
	//int32_t msgLen = (int32_t)msg.length();

	//std::string& head_string = proxy_head.GetHeadString();
	//int32_t headLen = (int32_t)head_string.length();
	//uint32_t net_headLen = boost::asio::detail::socket_ops::host_to_network_long(headLen);

	//sendString.reserve(TY_MSG_HEAD_LEN + msgLen + headLen + TY_MSG_HEAD_LEN);
	//sendString.append((const char*)&msg_id, TY_MSG_HEAD_LEN);
	//sendString.append((const char*)&net_headLen, TY_MSG_HEAD_LEN);
	//sendString.append(head_string.c_str(), headLen);
	//sendString.append(msg.c_str(), msgLen);
	//if (!connected())
	//{
	//	LOG_ERROR("default", "server_type[%d] proxy client is not connected!", service_type_);
	//	return -1;
	//}

	//::common::CNetMsgTransfer::out_tcp_for_proxy(*this, proxy_head, msg.c_str(), msg.length());
	//CClientBase::SendMsg(proxy_head, msg);
	::common::CNetMsgTransfer::out_tcp_for_proxy(*this, proxy_head, msg.c_str(), msg.length());
	return ::common::SUCCEED;
}


bool CProxyClientService::on_msg(uint32_t id)
{
	//std::string _msg_str(msg);
	//uint32_t _msg_id = (uint32_t)(boost::asio::detail::socket_ops::network_to_host_long(*(TY_MSG_HEAD_TYPE*)_msg_str.c_str()));

	//std::string tmp_str;
	//tmp_str.assign(_msg_str, TY_MSG_HEAD_LEN, _msg_str.size() - TY_MSG_HEAD_LEN);

	//uint32_t headlen = (uint32_t)(boost::asio::detail::socket_ops::network_to_host_long(*(TY_MSG_HEAD_TYPE*)tmp_str.c_str()));
	//if (headlen >= tmp_str.length())
	//{
	//	LOG_ERROR("default", "unpack msg err! %s", tmp_str.c_str());
	//	return false;
	//}
	//std::string _msg_head_str;
	//_msg_head_str.assign(tmp_str, TY_MSG_HEAD_LEN, headlen);
	::common::CProxyHead head;

	std::string _msg_content_str;
	/*uint32_t extend_len = TY_MSG_HEAD_LEN + headlen;*/
	::common::CNetMsgTransfer::in_tcp_for_proxy(*this, _msg_content_str, head);

	LOG_DEBUG("default", "recv msg from[%d:%d:%d] to[%d:%d:%d], content:[%s]", head.src_area_id, head.src_server_type, head.src_server_id, head.dst_area_id, head.dst_server_type, head.dst_server_id, _msg_content_str.c_str());

	if (service_ == NULL) {
		return -1;
	}

	//服务接收 proxy 消息
	//service_->AddServerMsg(_msg_id, _msg_content_str, head);
	CProxySocketMsg server_msg;
	server_msg.SetMsg(head, _msg_content_str, 0);
	service_->ProcessServerMsg(server_msg);
	return true;
}

void CProxyClientService::OnConnect()
{
	if ( service_type_ == PLATFORM_SERVICE)
	{
		SendRegisterPlatformProxyService();
	}
	else
	{
		LOG_DEBUG("default", "on connect ProxyService %s:%d succeed!", ip_, port_);
		LOG_DEBUG("default", "begin register proxy!!");
		SendRegisterProxyService();
	}
}

void CProxyClientService::SendRegisterProxyService()
{
	common::CProxyHead head;
	head.src_server_type = service_type_;
	head.src_server_id = service_id_;
	head.src_area_id = GameHostManager::GetInstance().GetServerAreaId();
	head.dst_server_type = PROXY_SERVICE;
	head.dst_server_id = 0;
	head.dst_area_id = 0;
	head.msg_id = register_to_proxy;

	Json::Value mjson;
	mjson["register"] = 0;
	std::string msg = JsonWriter(mjson);
	SendMsg(head, msg);
}

int CProxyClientService::SendMsg2Platform(uint32_t msg_id, const std::string& msg)
{
	return SendServiceMsg(msg_id, msg, 0, PLATFORM_SERVICE, 0, 0, 0, 1);
}

void CProxyClientService::SendRegisterPlatformProxyService()
{
	common::CProxyHead head;
	head.src_server_type = service_type_;
	head.src_server_id = service_id_;
	head.src_area_id = GameHostManager::GetInstance().GetServerAreaId();
	head.dst_server_type = 0;
	head.dst_server_id = 0;
	head.dst_area_id = 0;
	head.msg_id = register_to_platform;

	Json::Value mjson;
	mjson["register"] = 0;
	std::string msg = JsonWriter(mjson);
	SendMsg(head, msg);
}

void CProxyClientService::SetMapArea(uint32_t map_area)
{
	map_area_ = map_area;
}

// void CProxyClientService::CheckPingTime()
// {
//     if( proxy_client_.connected( ) == false )
//     {
//         return;
//     }
//     if( REAL_SEC - proxy_client_.last_ping_time( ) > proxy_ping_time.value( ) )
//     {
//         proxy_client_.Disconnect( );
//         LOG_ERROR( "default", "PROXY SERVICE IS OUT OF PING" );
//         return;
//     }
//     proxy_client_.SendPingMsg( );
// }


